// (C) 2012, Vladimir Belov  -Delay
// (C) 2012, Witti           -Limiter
// (C) 2008, Lubomir Ivanov  -Filter
//
// NO WARRANTY IS GRANTED. THIS PLUG-IN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
// WARRANTY OF ANY KIND. NO LIABILITY IS GRANTED, INCLUDING, BUT NOT LIMITED TO,
// ANY DIRECT OR INDIRECT,  SPECIAL,  INCIDENTAL OR CONSEQUENTIAL DAMAGE ARISING
// OUT OF  THE  USE  OR INABILITY  TO  USE  THIS PLUG-IN,  COMPUTER FAILTURE  OF
// MALFUNCTION INCLUDED.  THE USE OF THE SOURCE CODE,  EITHER  PARTIALLY  OR  IN
// TOTAL, IS ONLY GRANTED,  IF USED IN THE SENSE OF THE AUTHOR'S INTENTION,  AND
// USED WITH ACKNOWLEDGEMENT OF THE AUTHOR. FURTHERMORE IS THIS PLUG-IN A  THIRD
// PARTY CONTRIBUTION,  EVEN IF INCLUDED IN REAPER(TM),  COCKOS INCORPORATED  OR
// ITS AFFILIATES HAVE NOTHING TO DO WITH IT.  LAST BUT NOT LEAST, BY USING THIS
// PLUG-IN YOU RELINQUISH YOUR CLAIM TO SUE IT'S AUTHOR, AS WELL AS THE CLAIM TO
// ENTRUST SOMEBODY ELSE WITH DOING SO.
//
//******************************************************************************
//Reference : Apple.com AU tutorial (port from C++)
//******************************************************************************

desc:Digilay V2.0

slider1:0<0,2,1{Stereo,Cross,Ping-Pong}>Mode
slider2:0<0,1000,1>Delay (ms) 0 - beat sync
slider3:3<20,100,1{2,1,1/2,1/4,1/8,1/16,1/32,1/64}>Delay 
slider4:1<0,2,1{Dot,1,Trio}>Variation
slider5:1<0.5,1.5,0.01>unsync
slider6:-6<-60,0,1>FeedBack dB    (-60 = noun FB )
slider7:-0<-1,1,0.01>Damping L<-0->R
slider8:-1<-1,1,0.01>Direction       
slider9:1<0,1,0.01>Dry << Balance >> Wet
slider10:0<0,1,1>-
slider11:1<0,1,1{Pre Filtr,Post Filtr}>FB Position
slider12:70<0,100,0.05>Cutoff (Scale)
slider13:0<-25,25,0.05>Res (dB)

@init
ext_noinit=0;

mX1l=mX2l=mY1l=mY2l=mX1r=mX2r=mY1r=mY2r=0;

transfer_A = (1/300)-1;
transfer_B = 1 * pow(1,-transfer_A);

attack = exp(-1/(0.004/1000*srate));
release = exp(-1/(300/1000*srate));
envelope_decay = exp(-1/(100/1000*srate));


@slider
slider6==-60 ? fb=0 : fb=10^(slider6/20);

slider1==2 ?
  (
  fbl=fb^(0.5+slider7/2);
  fbr=fb^(0.5-slider7/2)  ): 

  (
  fbl=fb*(1+min(0,0-slider7))^0.5;
  fbr=fb*(1+min(0,slider7))^0.5 );

slider9 < 0 ? slider9=0;
slider9 > 1 ? slider9=1;
wet=slider9 ; dry=1-slider9;

// Directions
l=0.5-slider8/2;
r=0.5+slider8/2;
kl=wet*l;
kr=wet*r;

//frequency
sx = 16+slider12*1.20103;
cx = floor(exp(sx*log(1.059))*8.17742);
res = slider13;

//coefficients
cutoff = 2 * cx / srate;
res = pow(10, 0.05 * -res);
k = 0.5 * res * sin($pi * cutoff);
c1 = 0.5 * (1 - k) / (1 + k);
c2 = (0.5 + c1) * cos($pi * cutoff);
c3 = (0.5 + c1 - c2) * 0.25;
    
mA0 = 2 * c3;
mA1 = 2 * 2 * c3;
mA2 = 2 * c3;
mB1 = 2 * -c2;
mB2 = 2 * c1;

@block
beat=60*srate/tempo;

//beat or ms
slider2==0 ?
 blenght=beat*8/(1.5^(slider4-1)*2^slider3):
 blenght=abs(slider2*srate/1000);

//temp var
d =floor(blenght*slider5);
d2=blenght*2-d;

@sample
inl=spl0;
inr=spl1;

  //  Stereo
  slider1==0 ?
    (
    bl[0] = inl + bl[0]*fbl;
    br[d] = inr + br[d]*fbr  );

  //  Cross
  slider1==1 ?
    (
    bt=bl[0];
    bl[0] = inr + br[d]*fbl;
    br[d] = inl + bt   *fbr  );

  //  Ping-Pong Delay
  slider1==2 ? 

    (
    //feddback
    bt=bl[0];
    bl[0] = br[d]*fbl+(inl+inr)/2;
    br[d] = bt   *fbr         );

//counts
bl+=1; bl>=d   ? bl=0;
br+=1; br>=d2  ? br=0;

//filter
flil = bl[0];
flir = br[d];

flol = mA0*flil + mA1*mX1l + mA2*mX2l - mB1*mY1l - mB2*mY2l;
mX2l = mX1l;
mX1l = flil;
mY2l = mY1l;
mY1l = flol;
 
flor = mA0*flir + mA1*mX1r + mA2*mX2r - mB1*mY1r - mB2*mY2r;
mX2r = mX1r;
mX1r = flir;
mY2r = mY1r;
mY1r = flor;

det = max(abs(flol),abs(flor));
det += 0.000000000001;
env = det >= env ? det : det+envelope_decay*(env-det);
transfer_gain = env > 1 ? pow(env,transfer_A):1;
gain = transfer_gain < gain ?

 transfer_gain+attack *(gain-transfer_gain) : 
 transfer_gain+release*(gain-transfer_gain);

flol *= gain*0.98;
flor *= gain*0.98;

slider11 == 1 ? (
bl[0] = flol;
br[d] = flor;   );

//out
spl0 = inl*dry + flol*kl + flor*kr;
spl1 = inr*dry + flor*kl + flol*kr;


@gfx 100 10
gfx_x=gfx_y=5;
gfx_lineto(gfx_x, gfx_y,0);
gfx_r=gfx_b=0;
gfx_g=gfx_a=1;
gfx_drawchar($'F');
gfx_drawchar($' ');
gfx_drawchar($'=');
gfx_drawchar($' ');
gfx_drawnumber(cx,0);
gfx_drawchar($' ');
gfx_drawchar($'H');
gfx_drawchar($'z');

